package ws

import (
	"context"

	"gitee.com/crack007/goose/gscore"
	"gitee.com/crack007/goose/gsutil"
	"github.com/spf13/cobra"
)

type ServerBuilder struct {
	Port uint16
	gscore.BaseBuilder
	WsServerHandle IWsServerHandle
	serverName     string
	SessionBuilder *SessionBuilder
}

func NewServerBuilder(iWsServerHandle IWsServerHandle, sessionBuilder *SessionBuilder) *ServerBuilder {
	ctx, cancelFunc := context.WithCancel(context.Background())
	return &ServerBuilder{
		WsServerHandle: iWsServerHandle,
		BaseBuilder: gscore.BaseBuilder{
			Ctx:        ctx,
			CancelFunc: cancelFunc,
			CobraCmd:   &cobra.Command{},
		},
		SessionBuilder: sessionBuilder,
		Port:           10000,
	}
}

func (x *ServerBuilder) ServerName() string {
	return x.serverName
}

func (x *ServerBuilder) SetServerName(serverName string) {
	x.serverName = serverName
}

func (x *ServerBuilder) Build() (gscore.IServer, error) {
	sessionManager := NewSessionManager()
	wsServer := &Server{
		port:    x.Port,
		Builder: x,
		BaseServer: gscore.BaseServer{
			IsGraceful: true,
			Ctx:        x.GetCtx(),
			Cancel:     x.GetCancelFunc(),
			WorkPath:   gsutil.RuntimeUtil.GetWorkPath(),
		},
		SessionBuilder: x.SessionBuilder,
		SessionManager: sessionManager,
		MessageManager: NewMessageManager(sessionManager, x.SessionBuilder, x.GetCtx()),
	}
	wsServer.SetServerName(x.serverName)
	wsServer.SetCobraCmd(x.GetCobraCmd())
	return wsServer, nil
}

func (x *ServerBuilder) GetHandle() gscore.IHandle {
	return x.WsServerHandle
}

func (x *ServerBuilder) GetPort() uint16 {
	return x.Port
}

func (x *ServerBuilder) EnablePortFlag(defaultPort uint16) *ServerBuilder {
	x.GetCobraCmd().PersistentFlags().Uint16VarP(&x.Port, "port", "p", defaultPort, "http server port")
	return x
}
